#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define KB_SIZE 1024
#define MB_SIZE (1024 * KB_SIZE)
#define GB_SIZE (1024 * MB_SIZE)
#define BUF_4K (4 * KB_SIZE)

void show_cache_buffer_info()
{
    system("free -m");
    system("grep -E 'Buffers|Cached' /proc/meminfo");
}

void help()
{
    char *help_str = "\
    默认 正常读文件 \n\
    1 n NOREUSE \n\
    2 d DONTNEED\n";
    printf("%s", help_str);
}

int main(int argc, char *argv[])
{
    int ret = 0;
    // 1.生产大文件
    if((ret=access("testfile.img", F_OK)) != 0)
        system("dd if=/dev/zero of=testfile.img bs=1M count=512");
    // 2.清空系统缓存
    system("sync; echo 3 > /proc/sys/vm/drop_caches");
    show_cache_buffer_info();

    // 3.打开文件
    int fd = open("testfile.img", O_RDONLY);
    if (fd < 0)
    {
        perror("open");
        exit(1);
    }

    // // 4.读缓存优化 --> 释放缓存,要在读取完之后再释放
    // if (argc == 2)
    // {
    //     char opt = *argv[1];
    //     if (opt == '1')
    //         posix_fadvise(fd, 0, 0, POSIX_FADV_NOREUSE);
    //     if (opt == '2')
    //         posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
    // }

    // 5.读文件
    char buf[BUF_4K];
    while (1)
    {
        ret = read(fd, buf, BUF_4K);
        if (ret < 0)
        {
            perror("read");
            exit(1);
        }
        if (ret == 0)
        {
            break;
        }
    }

    // 6.释放读缓存
    fsync(fd);      // fsync将写数据落盘，这样才能确保 page cache全部释放成功
    if (argc == 2)
    {
        char opt = *argv[1];
        if (opt == '1' || opt == 'n')
            posix_fadvise(fd, 0, 0, POSIX_FADV_NOREUSE);
        if (opt == '2' || opt == 'd')
            posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
    }

    close(fd);
    show_cache_buffer_info();
}

/* 测试1
./4_read_cache_读缓存 优化_posix_fadvise.out
               total        used        free      shared  buff/cache   available
Mem:           15998        3566       11440         516         991       11636
Swap:           4096           0        4096


               total        used        free      shared  buff/cache   available
Mem:           15998        3555       10936         516        1506       11647
Swap:           4096           0        4096
 */

/* 测试2
./4_read_cache_读缓存 优化_posix_fadvise.out 1
               total        used        free      shared  buff/cache   available
Mem:           15998        3554       11452         516         990       11648
Swap:           4096           0        4096


               total        used        free      shared  buff/cache   available
Mem:           15998        3549       10942         516        1505       11653
Swap:           4096           0        4096
 */

/* 测试3
./4_read_cache_读缓存 优化_posix_fadvise.out 2
               total        used        free      shared  buff/cache   available
Mem:           15998        3562       11444         516         991       11640
Swap:           4096           0        4096


               total        used        free      shared  buff/cache   available
Mem:           15998        3560       11442         516         994       11642
 */

/* 测试结论
POSIX_FADV_DONTNEED 能够主动释放读缓存，但是释放的时机不确定，所以需要配合 fsync() 使用

 */